package cz.cvut.fit.mi.dpo.mvc.view.tables;

import cz.cvut.fit.mi.dpo.mvc.controller.Controller;
import cz.cvut.fit.mi.dpo.mvc.model.IReadable;
import cz.cvut.fit.mi.dpo.mvc.model.elements.AElement;
import cz.cvut.fit.mi.dpo.mvc.model.elements.ElementCollection;
import cz.cvut.fit.mi.dpo.mvc.view.AView;

import java.awt.*;
import javax.swing.*;
import javax.swing.table.AbstractTableModel;

/**
 * @author David Pertl
 * @author Martin Štekl <steklmar@fit.cvut.cz>
 */
public abstract class ATable extends AView {

	protected JTable table;

	public ATable(Controller controller, IReadable model, String name) {
		super(controller, model);
		setLayout(new BorderLayout());
		setBorder(BorderFactory.createTitledBorder(name));
		setPreferredSize(new Dimension(400, 0));

		JScrollPane scrollPane = new JScrollPane();
		table = new JTable();
		scrollPane.setViewportView(table);
		add(scrollPane);
	}

	@Override
	public void fire() {
		AbstractTableModel model = (AbstractTableModel) table.getModel();
		model.fireTableDataChanged();
		super.fire();
	}

	protected abstract class AModel extends AbstractTableModel {

		private static final int COLUMN_COUNT = 4;

		private String[] columnNames;

		protected AModel(String[] columnNames) {
			this.columnNames = columnNames;
		}

		@Override
		public String getColumnName(int column) {
			return columnNames[column];
		}

		@Override
		public int getColumnCount() {
			return COLUMN_COUNT;
		}

		@Override
		public int getRowCount() {
			return getModel().size();
		}

		@Override
		public boolean isCellEditable(int row, int col) {
			return col > 0;
		}

		@Override
		public Object getValueAt(int rowIndex, int columnIndex) {
			return getValueFrom(getModel().get(rowIndex), columnIndex);
		}

		@Override
		public void setValueAt(Object value, int rowIndex, int columnIndex) {
			if (controller.validateInteger(value)) {
				setValueFor(getModel().get(rowIndex), columnIndex, Integer.parseInt(value.toString()));
			}
		}

		protected abstract ElementCollection<? extends AElement> getModel();

		protected abstract void setValueFor(AElement element, int columnIndex, int value);

		protected Object getValueFrom(AElement element, int columnIndex) {
			Object result;
			switch (columnIndex) {
				case 0:
					result = element.getId();
					break;
				case 1:
					result = element.getX();
					break;
				case 2:
					result = element.getY();
					break;
				default:
					throw new IllegalArgumentException("Unknown column index [" + columnIndex + "].");
			}
			return result;
		}

	}

}
